// Content script for Web Element Selector extension

// 使用IIFE避免全局变量污染
(function () {
  // 检查是否已经初始化过，避免重复初始化
  if (window.webElementSelector) {
    return;
  }

  class WebElementSelector {
    constructor() {
      this.isActive = false;
      this.isSelecting = false;
      this.isRecording = true; // 默认启用录制模式
      this.selectedElements = [];
      this.currentHighlightedElement = null;
      this.panel = null;
      this.tooltip = null;

      // 初始化绑定的事件处理器，避免多次绑定问题
      this.boundMouseOver = this.handleMouseOver.bind(this);
      this.boundMouseOut = this.handleMouseOut.bind(this);
      this.boundClick = this.handleClick.bind(this);
      this.boundKeyDown = this.handleKeyDown.bind(this);

      // 加载用户配置
      this.loadConfig();

      // Initialize the extension
      this.initialize();
    }

    // Initialize the extension
    initialize() {
      // 移除可能存在的重复事件监听器
      this.removeAllEventListeners();

      // Listen for messages from the background script
      chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
        if (message.action === "toggleSelector") {
          this.toggleSelector();
          // 发送响应表明消息已收到
          if (sendResponse) {
            sendResponse({ status: "success" });
          }
          return true; // 保持消息通道打开用于异步响应
        }
      });

      console.log("Web Element Selector 已初始化");
    }

    // 加载用户配置
    loadConfig() {
      chrome.storage.sync.get({
        siteSelectors: this.siteSelectors
      }, (items) => {
        // 合并保存的网站选择器与默认值
        this.siteSelectors = items.siteSelectors;
      });
    }

    // 保存用户配置
    saveConfig() {
      chrome.storage.sync.set({
        siteSelectors: this.siteSelectors
      }, () => {
        console.log('配置已保存');
      });
    }

    // Toggle the selector on/off
    toggleSelector() {
      if (this.isActive) {
        this.deactivate();
      } else {
        this.activate();
      }
    }

    // Activate the selector
    activate() {
      if (this.isActive) return;

      this.isActive = true;
      this.isSelecting = true;

      // Create the panel
      this.createPanel();

      // Create the tooltip
      this.createTooltip();

      // 检测网站类型，启用特定选择器
      const siteType = this.detectSiteType();
      console.log('当前网站类型:', siteType);

      // Add event listeners
      document.addEventListener('mouseover', this.boundMouseOver);
      document.addEventListener('mouseout', this.boundMouseOut);
      document.addEventListener('click', this.boundClick, true);
      document.addEventListener('keydown', this.boundKeyDown);

      console.log("Web Element Selector 已激活");
    }

    // Deactivate the selector
    deactivate() {
      if (!this.isActive) return;

      this.isActive = false;
      this.isSelecting = false;

      // Remove the panel
      if (this.panel) {
        document.body.removeChild(this.panel);
        this.panel = null;
      }

      // Remove the tooltip
      if (this.tooltip) {
        document.body.removeChild(this.tooltip);
        this.tooltip = null;
      }

      // Remove event listeners
      this.removeAllEventListeners();

      // Remove highlights from all elements
      this.removeAllHighlights();

      // 清空选择的元素缓存
      this.selectedElements = [];

      console.log("Web Element Selector 已停用");
    }

    // Remove all event listeners
    removeAllEventListeners() {
      document.removeEventListener('mouseover', this.boundMouseOver);
      document.removeEventListener('mouseout', this.boundMouseOut);
      document.removeEventListener('click', this.boundClick, true);
      document.removeEventListener('keydown', this.boundKeyDown);
    }

    // Create the floating panel
    createPanel() {
      // 移除已存在的面板
      const existingPanel = document.getElementById('web-element-selector-panel');
      if (existingPanel) {
        document.body.removeChild(existingPanel);
      }

      // Create the panel
      this.panel = document.createElement('div');
      this.panel.id = 'web-element-selector-panel';
      this.panel.style.position = 'fixed';
      this.panel.style.top = '20px';
      this.panel.style.right = '20px';
      this.panel.style.zIndex = '10000000';
      this.panel.style.cursor = 'default';
      this.panel.style.width = '600px'; // 初始宽度
      this.panel.style.height = '500px'; // 初始高度
      this.panel.style.minWidth = '400px'; // 最小宽度
      this.panel.style.minHeight = '200px'; // 最小高度
      this.panel.style.boxSizing = 'border-box'; // 确保padding不影响尺寸计算
      this.panel.style.overflow = 'hidden'; // 防止内容溢出
      // 使用flexbox布局
      this.panel.style.display = 'flex';
      this.panel.style.flexDirection = 'column';

      // Create the header
      const header = document.createElement('div');
      header.id = 'web-element-selector-header';
      header.textContent = '网页元素选择器';
      header.style.cursor = 'move';
      header.style.userSelect = 'none';
      header.style.flexShrink = '0'; // 不允许header缩小

      // 拖动逻辑
      let isDragging = false;
      let dragOffsetX = 0;
      let dragOffsetY = 0;
      header.addEventListener('mousedown', (e) => {
        isDragging = true;
        const rect = this.panel.getBoundingClientRect();
        dragOffsetX = e.clientX - rect.left;
        dragOffsetY = e.clientY - rect.top;
        document.body.style.userSelect = 'none';
      });
      document.addEventListener('mousemove', (e) => {
        if (isDragging) {
          this.panel.style.left = (e.clientX - dragOffsetX) + 'px';
          this.panel.style.top = (e.clientY - dragOffsetY) + 'px';
          this.panel.style.right = 'auto';
        }
      });
      document.addEventListener('mouseup', () => {
        isDragging = false;
        document.body.style.userSelect = '';
      });

      // Create the close button
      const closeButton = document.createElement('span');
      closeButton.id = 'web-element-selector-close';
      closeButton.textContent = '×';
      closeButton.addEventListener('click', () => this.deactivate());
      header.appendChild(closeButton);

      // Create the URL section
      const url = document.createElement('div');
      url.id = 'web-element-selector-url';
      url.textContent = window.location.href;
      url.style.flexShrink = '0'; // 不允许url区域缩小

      // 创建内容区域容器（包含表格和操作按钮）
      const contentContainer = document.createElement('div');
      contentContainer.style.display = 'flex';
      contentContainer.style.flexDirection = 'column';
      contentContainer.style.flex = '1';  // 内容区域占用所有可用空间
      contentContainer.style.overflow = 'hidden'; // 防止内容溢出

      // Create the list of selected elements
      const list = document.createElement('div');
      list.id = 'web-element-selector-list';
      list.style.minHeight = '100px'; // 设置最小高度
      list.style.overflowY = 'auto';  // 垂直方向可滚动
      list.style.flex = '1'; // 让列表区域自动填充内容区域可用空间

      // Create the actions section
      const actions = document.createElement('div');
      actions.id = 'web-element-selector-actions';
      actions.style.flexShrink = '0'; // 不允许按钮区域缩小
      actions.style.marginTop = '10px'; // 与表格区域保持一定间距
      actions.style.display = 'flex';
      actions.style.justifyContent = 'flex-end';
      actions.style.flexWrap = 'wrap';  // 按钮较多时可换行

      // 创建录制模式切换按钮
      const toggleRecordingButton = document.createElement('button');
      toggleRecordingButton.className = 'web-element-selector-button';
      toggleRecordingButton.textContent = this.isRecording ? '非录制模式' : '录制模式';
      toggleRecordingButton.addEventListener('click', () => {
        this.isRecording = !this.isRecording;
        toggleRecordingButton.textContent = this.isRecording ? '非录制模式' : '录制模式';
      });

      // Create the export buttons
      const exportCsvButton = document.createElement('button');
      exportCsvButton.className = 'web-element-selector-button';
      exportCsvButton.textContent = '导出CSV';
      exportCsvButton.addEventListener('click', () => this.exportToCsv());

      const exportJsonButton = document.createElement('button');
      exportJsonButton.className = 'web-element-selector-button';
      exportJsonButton.textContent = '导出JSON';
      exportJsonButton.addEventListener('click', () => this.exportToJson());

      const exportYamlButton = document.createElement('button');
      exportYamlButton.className = 'web-element-selector-button';
      exportYamlButton.textContent = '导出YAML';
      exportYamlButton.addEventListener('click', () => this.exportToYaml());

      const copyButton = document.createElement('button');
      copyButton.className = 'web-element-selector-button';
      copyButton.textContent = '复制';
      copyButton.addEventListener('click', () => this.copyToClipboard());

      // Add all elements to the panel
      actions.appendChild(toggleRecordingButton);
      actions.appendChild(exportCsvButton);
      actions.appendChild(exportJsonButton);
      actions.appendChild(exportYamlButton);
      actions.appendChild(copyButton);

      // 组合内容区域
      contentContainer.appendChild(list);
      contentContainer.appendChild(actions);

      this.panel.appendChild(header);
      this.panel.appendChild(url);
      this.panel.appendChild(contentContainer);

      // 添加调节大小的手柄
      const resizeHandle = document.createElement('div');
      resizeHandle.className = 'web-element-selector-resize-handle';
      resizeHandle.style.position = 'absolute';
      resizeHandle.style.right = '0';
      resizeHandle.style.bottom = '0';
      resizeHandle.style.width = '15px';
      resizeHandle.style.height = '15px';
      resizeHandle.style.cursor = 'nwse-resize'; // 右下角调整大小的光标
      resizeHandle.style.backgroundImage = 'linear-gradient(135deg, transparent 10px, rgba(0,0,0,0.3) 11px, transparent 11px)';
      resizeHandle.style.backgroundSize = '12px 12px';
      resizeHandle.style.backgroundRepeat = 'no-repeat';
      resizeHandle.style.backgroundPosition = 'right bottom';
      resizeHandle.style.zIndex = '10';

      // 调整大小的交互逻辑
      let isResizing = false;
      let originalWidth, originalHeight, originalX, originalY;

      resizeHandle.addEventListener('mousedown', (e) => {
        // 阻止事件冒泡，避免触发面板的拖动
        e.stopPropagation();

        isResizing = true;
        const rect = this.panel.getBoundingClientRect();
        originalWidth = rect.width;
        originalHeight = rect.height;
        originalX = e.clientX;
        originalY = e.clientY;
        document.body.style.userSelect = 'none'; // 防止拖动时选中文本
      });

      document.addEventListener('mousemove', (e) => {
        if (!isResizing) return;

        // 计算新的宽高（右下角：向右下拖动变大）
        const newWidth = Math.max(400, originalWidth + (e.clientX - originalX)); // 限制最小宽度
        const newHeight = Math.max(200, originalHeight + (e.clientY - originalY)); // 限制最小高度
        this.panel.style.width = newWidth + 'px';
        this.panel.style.height = newHeight + 'px';
      });

      document.addEventListener('mouseup', () => {
        if (isResizing) {
          isResizing = false;
          document.body.style.userSelect = ''; // 恢复文本选择
        }
      });

      this.panel.appendChild(resizeHandle);

      // Add the panel to the page
      document.body.appendChild(this.panel);

      // Show the panel
      this.panel.style.display = 'flex'; // 保持为flex布局
    }

    // Create the tooltip for showing locators
    createTooltip() {
      // 移除已存在的提示框
      const existingTooltip = document.querySelector('.web-element-selector-tooltip');
      if (existingTooltip) {
        document.body.removeChild(existingTooltip);
      }

      this.tooltip = document.createElement('div');
      this.tooltip.className = 'web-element-selector-tooltip';
      this.tooltip.style.display = 'none';
      document.body.appendChild(this.tooltip);
    }

    // Handle mouse over event
    handleMouseOver(event) {
      if (!this.isSelecting) return;

      // Prevent highlighting the panel or tooltip
      if (event.target.closest('#web-element-selector-panel') ||
        event.target.closest('.web-element-selector-tooltip')) {
        return;
      }

      // Highlight the element
      this.highlightElement(event.target);

      // Show the tooltip with locators
      this.showLocatorsTooltip(event.target, event.clientX, event.clientY);
    }

    // Handle mouse out event
    handleMouseOut(event) {
      if (!this.isSelecting) return;

      // Remove the highlight
      this.removeHighlight(event.target);

      // Hide the tooltip
      this.hideTooltip();
    }

    // Handle click event
    handleClick(event) {
      if (!this.isSelecting) return;

      // Prevent clicking on the panel or tooltip
      if (event.target.closest('#web-element-selector-panel') ||
        event.target.closest('.web-element-selector-tooltip')) {
        return;
      }

      if (this.isRecording) {
        event.preventDefault();
        event.stopPropagation();

        // 判断是否已选中
        if (this.selectedElements.includes(event.target)) {
          this.deselectElement(event.target);
        } else {
          this.selectElement(event.target);
        }
      }
      // 非录制模式下不阻止默认行为，页面保持可交互
    }

    // Handle key down event (Escape to exit)
    handleKeyDown(event) {
      if (event.key === 'Escape') {
        this.deactivate();
      }
    }

    // Highlight an element
    highlightElement(element) {
      if (this.currentHighlightedElement === element) return;

      // Remove highlight from the previous element
      if (this.currentHighlightedElement) {
        this.removeHighlight(this.currentHighlightedElement);
      }

      // Highlight the new element
      element.classList.add('web-element-selector-highlight');
      this.currentHighlightedElement = element;
    }

    // Remove highlight from an element
    removeHighlight(element) {
      element.classList.remove('web-element-selector-highlight');

      if (this.currentHighlightedElement === element) {
        this.currentHighlightedElement = null;
      }
    }

    // Remove all highlights
    removeAllHighlights() {
      const highlightedElements = document.querySelectorAll('.web-element-selector-highlight');
      highlightedElements.forEach(element => {
        element.classList.remove('web-element-selector-highlight');
      });

      const selectedElements = document.querySelectorAll('.web-element-selector-selected');
      selectedElements.forEach(element => {
        element.classList.remove('web-element-selector-selected');
      });

      this.currentHighlightedElement = null;
    }

    // Select an element
    selectElement(element) {
      // 检查元素是否已被选中
      if (this.selectedElements.includes(element)) {
        return;
      }

      // Add the element to the list
      this.selectedElements.push(element);

      // Mark the element as selected
      element.classList.add('web-element-selector-selected');

      // Add the element to the panel
      this.addElementToPanel(element);
    }

    // Add an element to the panel
    addElementToPanel(element) {
      const list = document.getElementById('web-element-selector-list');

      // 创建表头（仅在第一次添加元素时创建）
      if (list.children.length === 0) {
        // 增加"推荐定位器"列，放在第一列
        const locatorTypes = ['推荐定位器', 'ID', 'Tag Name', 'Class Name', 'CSS', 'XPath', 'Link Text', 'Name'];

        // 创建表头行
        const headerRow = document.createElement('div');
        headerRow.className = 'web-element-selector-header-row';

        // 创建表头单元格
        locatorTypes.forEach(type => {
          const headerCell = document.createElement('div');
          headerCell.className = 'web-element-selector-header-cell';
          headerCell.textContent = type;

          // 添加调整宽度的控件
          const resizer = document.createElement('div');
          resizer.className = 'web-element-selector-header-cell-resizer';
          headerCell.appendChild(resizer);

          // 添加调整宽度的事件
          this.addResizerEvents(resizer);

          headerRow.appendChild(headerCell);
        });

        // 添加表头到列表
        list.appendChild(headerRow);
      }

      // 创建数据行
      const item = document.createElement('div');
      item.className = 'web-element-selector-item';

      // 获取定位器
      const locators = this.generateLocators(element);
      // 获取推荐定位器
      const aquaLocator = this.generateAquaLocator(element);

      // 定位器顺序：增加"推荐定位器"列，放在第一列
      const locatorTypes = ['推荐定位器', 'ID', 'Tag Name', 'Class Name', 'CSS', 'XPath', 'Link Text', 'Name'];

      // 创建数据单元格
      locatorTypes.forEach(type => {
        const cell = document.createElement('div');
        cell.className = 'web-element-selector-cell';

        // 对于推荐定位器，使用Aqua算法结果
        if (type === '推荐定位器') {
          if (aquaLocator) {
            cell.textContent = aquaLocator;
            cell.style.color = '#1976d2'; // 使用蓝色突出显示
            cell.style.fontWeight = 'bold';
          } else {
            cell.textContent = '无唯一推荐定位器';
            cell.style.color = '#d32f2f'; // 红色提示
            cell.style.fontStyle = 'italic';
          }
        } else {
          cell.textContent = locators[type] || '';
        }

        item.appendChild(cell);
      });

      // 添加数据行到列表
      list.appendChild(item);
    }

    // Generate locators for an element
    generateLocators(element) {
      const locators = {
        ID: "",
        Name: "",
        "Class Name": "",
        "Tag Name": element.tagName.toLowerCase(),
        "Link Text": "",
        CSS: this.getSimpleCssSelector(element),
        XPath: this.getSimpleXPath(element)
      };

      // ID
      if (element.id) {
        locators.ID = element.id;
      }

      // Name
      if (element.name) {
        locators.Name = element.name;
      }

      // Class Name
      if (element.className && element.className.trim() !== '') {
        const allClassNames = element.className.split(' ').filter(c => {
          return c !== '' &&
            c !== 'web-element-selector-highlight' &&
            c !== 'web-element-selector-selected';
        });

        if (allClassNames.length > 0) {
          locators["Class Name"] = allClassNames.join(' ');
        }
      }

      // Link Text (只适用于<a>标签)
      if (element.tagName.toLowerCase() === 'a' && element.textContent && element.textContent.trim() !== '') {
        const text = element.textContent.trim();
        const processedText = this.truncateString(text, 50);

        if (processedText) {
          locators["Link Text"] = processedText;
        }
      }

      return locators;
    }

    // 生成简洁的CSS选择器，优先使用标签+属性
    getSimpleCssSelector(element) {
      if (!element) return '';
      const tag = element.tagName.toLowerCase();

      // 如果有ID，直接返回标签#ID
      if (element.id) {
        return `${tag}#${element.id}`;
      }

      // 如果有name属性，使用标签[name="value"]
      if (element.name) {
        return `${tag}[name="${element.name}"]`;
      }

      // 如果有独特的属性，使用它们
      for (const attr of ['role', 'aria-label', 'title', 'placeholder']) {
        if (element.getAttribute(attr)) {
          const attrValue = element.getAttribute(attr);
          return `${tag}[${attr}="${attrValue}"]`;
        }
      }

      // 尝试使用第一个类名（如果有）
      const classes = element.className.split(' ').filter(c => {
        return c !== '' &&
          c !== 'web-element-selector-highlight' &&
          c !== 'web-element-selector-selected';
      });

      if (classes.length > 0) {
        return `${tag}.${classes[0]}`;
      }

      // 尝试使用父元素ID+子元素标签
      const parent = element.parentElement;
      if (parent && parent.id) {
        // 查找相同标签的兄弟元素
        const siblings = Array.from(parent.children).filter(e => e.tagName === element.tagName);
        if (siblings.length === 1) {
          return `#${parent.id} > ${tag}`;
        } else {
          const index = siblings.indexOf(element) + 1;
          return `#${parent.id} > ${tag}:nth-child(${index})`;
        }
      }

      // 回退到更简单的选择器，只包含标签和位置
      return `${tag}:nth-of-type(${this.getNthOfType(element)})`;
    }

    // 获取元素是其类型中的第几个元素
    getNthOfType(element) {
      if (!element) return 1;
      let count = 0;
      let sibling = element;

      while (sibling) {
        if (sibling.nodeType === Node.ELEMENT_NODE && sibling.tagName === element.tagName) {
          count++;
        }
        sibling = sibling.previousElementSibling;
      }

      return count;
    }

    // 生成简洁的XPath，优先使用ID和属性
    getSimpleXPath(element) {
      if (!element) return '';

      // 如果元素有ID，直接使用ID定位
      if (element.id) {
        return `//${element.tagName.toLowerCase()}[@id="${element.id}"]`;
      }

      // 如果元素有name属性，使用name定位
      if (element.name) {
        return `//${element.tagName.toLowerCase()}[@name="${element.name}"]`;
      }

      // 尝试使用类名（只使用第一个有意义的类名）
      const classes = element.className.split(' ').filter(c => {
        return c !== '' &&
          c !== 'web-element-selector-highlight' &&
          c !== 'web-element-selector-selected';
      });

      if (classes.length > 0) {
        return `//${element.tagName.toLowerCase()}[contains(@class, "${classes[0]}")]`;
      }

      // 尝试使用文本内容定位（针对按钮、链接等）
      if (element.textContent && element.textContent.trim() !== '') {
        const text = element.textContent.trim();
        // 限制文本长度，并确保文本不包含引号
        const processedText = this.truncateString(text, 30).replace(/['"`]/g, '');

        if (processedText) {
          return `//${element.tagName.toLowerCase()}[contains(text(), "${processedText}")]`;
        }
      }

      // 尝试使用特殊属性定位
      for (const attr of ['role', 'aria-label', 'title', 'placeholder']) {
        if (element.getAttribute(attr)) {
          const attrValue = element.getAttribute(attr);
          return `//${element.tagName.toLowerCase()}[@${attr}="${attrValue}"]`;
        }
      }

      // 使用父元素+索引定位
      const parent = element.parentElement;
      if (parent) {
        if (parent.id) {
          // 如果父元素有ID
          return `//*[@id="${parent.id}"]/${element.tagName.toLowerCase()}[${this.getElementIndex(element)}]`;
        } else {
          // 计算当前元素是同类型中的第几个
          const index = this.getElementIndex(element);
          // 尝试获取父元素的简单路径（最多向上2级）
          const parentPath = this.getParentPath(parent, 2);
          return `${parentPath}/${element.tagName.toLowerCase()}[${index}]`;
        }
      }

      // 回退到基本的xpath，但不使用绝对路径
      return `//${element.tagName.toLowerCase()}[${this.getElementIndex(element)}]`;
    }

    // 获取元素在其父元素下的索引（同类型元素中的位置）
    getElementIndex(element) {
      if (!element || !element.parentNode) return 1;

      let count = 1;
      let sibling = element.previousSibling;

      while (sibling) {
        if (sibling.nodeType === Node.ELEMENT_NODE && sibling.tagName === element.tagName) {
          count++;
        }
        sibling = sibling.previousSibling;
      }

      return count;
    }

    // 获取父元素的路径，限制层级
    getParentPath(element, maxLevels = 2) {
      if (!element || maxLevels <= 0) return '';

      if (element.id) {
        return `//*[@id="${element.id}"]`;
      }

      if (element === document.body) {
        return '/html/body';
      }

      if (element.parentElement) {
        return this.getParentPath(element.parentElement, maxLevels - 1) +
          `/${element.tagName.toLowerCase()}[${this.getElementIndex(element)}]`;
      }

      return `/${element.tagName.toLowerCase()}[${this.getElementIndex(element)}]`;
    }

    // Show locators in a tooltip
    showLocatorsTooltip(element, x, y) {
      // 优先展示Aqua推荐定位器
      const aquaLocator = this.generateAquaLocator(element);
      let content = '<div><strong>推荐定位器：</strong></div>';
      if (aquaLocator) {
        content += `<div style=\"color:#1976d2;font-weight:bold;\">${aquaLocator}</div>`;
      } else {
        content += `<div style=\"color:#d32f2f;font-weight:bold;\">无唯一推荐定位器</div>`;
      }
      // 其余定位器
      const locators = this.generateLocators(element);
      const locatorTypes = ['ID', 'Name', 'Class Name', 'Tag Name', 'Link Text', 'CSS', 'XPath'];
      content += '<div style=\"margin-top:6px;\"><strong>其他可用定位器：</strong></div>';
      for (const type of locatorTypes) {
        if (locators[type]) {
          content += `<div>${type}: ${locators[type]}</div>`;
        }
      }
      this.tooltip.innerHTML = content;
      this.tooltip.style.top = `${y + 20}px`;
      this.tooltip.style.left = `${x + 10}px`;
      this.tooltip.style.display = 'block';
    }

    // Hide the tooltip
    hideTooltip() {
      if (this.tooltip) {
        this.tooltip.style.display = 'none';
      }
    }

    // Export the selected elements to CSV
    exportToCsv() {
      if (this.selectedElements.length === 0) {
        alert('尚未选择任何元素。');
        return;
      }

      // 增加"推荐定位器"列，放在第一列
      let csv = '元素类型,推荐定位器,ID,Tag Name,Class Name,CSS,XPath,Link Text,Name\n';

      this.selectedElements.forEach(element => {
        const locators = this.generateLocators(element);
        const aquaLocator = this.generateAquaLocator(element) || '无唯一推荐定位器';

        csv += `${element.tagName.toLowerCase()},"${aquaLocator}",${locators.ID},${locators["Tag Name"]},"${locators["Class Name"]}","${locators.CSS}","${locators.XPath}","${locators["Link Text"]}",${locators.Name}\n`;
      });

      // Create a blob and download the file
      const blob = new Blob([csv], { type: 'text/csv' });
      const url = URL.createObjectURL(blob);

      const a = document.createElement('a');
      a.href = url;
      a.download = `网页元素-${this.formatDate()}.csv`;
      a.click();

      URL.revokeObjectURL(url);
    }

    // Export the selected elements to JSON
    exportToJson() {
      if (this.selectedElements.length === 0) {
        alert('尚未选择任何元素。');
        return;
      }

      const elements = [];

      this.selectedElements.forEach(element => {
        const locators = this.generateLocators(element);
        const aquaLocator = this.generateAquaLocator(element);

        elements.push({
          elementType: element.tagName.toLowerCase(),
          text: element.textContent.trim().substring(0, 50),
          locators: {
            // 增加"推荐定位器"字段，放在最前面
            "推荐定位器": aquaLocator || '无唯一推荐定位器',
            ID: locators.ID,
            "Tag Name": locators["Tag Name"],
            "Class Name": locators["Class Name"],
            CSS: locators.CSS,
            XPath: locators.XPath,
            "Link Text": locators["Link Text"],
            Name: locators.Name
          }
        });
      });

      const json = JSON.stringify({
        url: window.location.href,
        timestamp: new Date().toISOString(),
        elements: elements
      }, null, 2);

      // Create a blob and download the file
      const blob = new Blob([json], { type: 'application/json' });
      const url = URL.createObjectURL(blob);

      const a = document.createElement('a');
      a.href = url;
      a.download = `网页元素-${this.formatDate()}.json`;
      a.click();

      URL.revokeObjectURL(url);
    }

    // Export the selected elements to YAML
    exportToYaml() {
      if (this.selectedElements.length === 0) {
        alert('尚未选择任何元素。');
        return;
      }

      const elements = [];

      this.selectedElements.forEach(element => {
        const locators = this.generateLocators(element);
        const aquaLocator = this.generateAquaLocator(element);

        elements.push({
          elementType: element.tagName.toLowerCase(),
          text: element.textContent.trim().substring(0, 50),
          locators: {
            // 增加"推荐定位器"字段，放在最前面
            "推荐定位器": aquaLocator || '无唯一推荐定位器',
            ID: locators.ID,
            "Tag Name": locators["Tag Name"],
            "Class Name": locators["Class Name"],
            CSS: locators.CSS,
            XPath: locators.XPath,
            "Link Text": locators["Link Text"],
            Name: locators.Name
          }
        });
      });

      const data = {
        url: window.location.href,
        timestamp: new Date().toISOString(),
        elements: elements
      };

      // Convert JSON to YAML
      let yaml = "---\n";
      yaml += `url: ${data.url}\n`;
      yaml += `timestamp: ${data.timestamp}\n`;
      yaml += "elements:\n";

      elements.forEach(element => {
        yaml += `  - elementType: ${element.elementType}\n`;
        yaml += `    text: ${element.text.replace(/"/g, '\\"')}\n`;
        yaml += "    locators:\n";
        yaml += `      推荐定位器: ${element.locators["推荐定位器"] ? '"' + element.locators["推荐定位器"].replace(/"/g, '\\"') + '"' : 'null'}\n`;
        yaml += `      ID: ${element.locators.ID || 'null'}\n`;
        yaml += `      Tag Name: ${element.locators["Tag Name"] || 'null'}\n`;
        yaml += `      Class Name: ${element.locators["Class Name"] ? '"' + element.locators["Class Name"].replace(/"/g, '\\"') + '"' : 'null'}\n`;
        yaml += `      CSS: ${element.locators.CSS ? '"' + element.locators.CSS.replace(/"/g, '\\"') + '"' : 'null'}\n`;
        yaml += `      XPath: ${element.locators.XPath ? '"' + element.locators.XPath.replace(/"/g, '\\"') + '"' : 'null'}\n`;
        yaml += `      Link Text: ${element.locators["Link Text"] ? '"' + element.locators["Link Text"].replace(/"/g, '\\"') + '"' : 'null'}\n`;
        yaml += `      Name: ${element.locators.Name || 'null'}\n`;
      });

      // Create a blob and download the file
      const blob = new Blob([yaml], { type: 'text/yaml' });
      const url = URL.createObjectURL(blob);

      const a = document.createElement('a');
      a.href = url;
      a.download = `网页元素-${this.formatDate()}.yaml`;
      a.click();

      URL.revokeObjectURL(url);
    }

    // Copy selected elements to clipboard
    copyToClipboard() {
      if (this.selectedElements.length === 0) {
        alert('尚未选择任何元素。');
        return;
      }

      const elements = this.selectedElements.map(element => {
        const locators = this.generateLocators(element);
        // 优先使用推荐定位器，其次再考虑ID、Name或Class Name
        const aquaLocator = this.generateAquaLocator(element);
        const mainIdentifier = aquaLocator ? `推荐定位器 = ${aquaLocator}` :
          locators.ID ? `ID = ${locators.ID}` :
            locators.Name ? `Name = ${locators.Name}` :
              locators["Class Name"] ? `Class = ${locators["Class Name"]}` :
                `Tag = ${locators["Tag Name"]}`;

        return `${element.tagName.toLowerCase()}: ${mainIdentifier}`;
      });

      const text = elements.join('\n');

      // Copy to clipboard
      navigator.clipboard.writeText(text).then(() => {
        alert('已复制到剪贴板！');
      }).catch(err => {
        console.error('复制失败:', err);
        alert('复制失败，请检查浏览器权限。');
      });
    }

    // Format date for filenames
    formatDate() {
      const date = new Date();
      return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`;
    }

    // Helper function to truncate a string
    truncateString(str, maxLength) {
      if (str.length <= maxLength) {
        return str;
      }
      return str.substring(0, maxLength) + '...';
    }

    // 取消选中元素
    deselectElement(element) {
      // 从已选中数组中移除
      this.selectedElements = this.selectedElements.filter(el => el !== element);
      // 移除选中样式
      element.classList.remove('web-element-selector-selected');
      // 从面板中移除对应条目
      const list = document.getElementById('web-element-selector-list');
      if (list) {
        // 通过ID或其他特征找到对应的元素
        const locators = this.generateLocators(element);
        const cssSelector = locators.CSS; // 使用CSS选择器作为更精确的标识
        const xpathSelector = locators.XPath; // 使用XPath作为备选标识
        const aquaLocator = this.generateAquaLocator(element); // 获取推荐定位器

        // 遍历列表中的所有项目（跳过表头行）
        Array.from(list.children).forEach((item, index) => {
          // 跳过表头行（第一个子元素）
          if (index === 0 && item.className === 'web-element-selector-header-row') {
            return;
          }

          if (item.className === 'web-element-selector-item') {
            const cells = item.querySelectorAll('.web-element-selector-cell');
            let shouldRemove = false;

            // 使用更精确的匹配逻辑，索引已调整为新的顺序（加入了推荐定位器列）
            // 推荐定位器:0, ID:1, Tag Name:2, Class Name:3, CSS:4, XPath:5, Link Text:6, Name:7
            if (aquaLocator && cells[0] && cells[0].textContent === aquaLocator) {
              // 首先尝试匹配推荐定位器
              shouldRemove = true;
            } else if (locators.ID && cells[1] && cells[1].textContent === locators.ID) {
              // 如果有ID，优先使用ID匹配
              shouldRemove = true;
            } else if (locators.Name && cells[7] && cells[7].textContent === locators.Name) {
              // 如果有Name，使用Name匹配
              shouldRemove = true;
            } else if (cssSelector && cells[4] && cells[4].textContent === cssSelector) {
              // 使用CSS选择器匹配
              shouldRemove = true;
            } else if (xpathSelector && cells[5] && cells[5].textContent === xpathSelector) {
              // 使用XPath匹配
              shouldRemove = true;
            }

            // 只有在确定应该移除时才移除
            if (shouldRemove) {
              list.removeChild(item);
              // 找到后立即返回，避免移除多个元素
              return;
            }
          }
        });
      }
    }

    // Add resizer events to header cells
    addResizerEvents(resizer) {
      resizer.addEventListener('mousedown', (startEvent) => {
        startEvent.preventDefault();
        startEvent.stopPropagation();

        const headerCell = resizer.parentElement;
        const columnIndex = Array.from(headerCell.parentElement.children).indexOf(headerCell);
        const initialX = startEvent.clientX;
        const initialWidth = headerCell.offsetWidth;
        let newWidth;

        // 获取所有行和对应的单元格
        const list = document.getElementById('web-element-selector-list');
        const allRows = list.children;

        const mouseMoveHandler = (moveEvent) => {
          moveEvent.preventDefault();
          const deltaX = moveEvent.clientX - initialX;
          newWidth = Math.max(80, initialWidth + deltaX); // 最小宽度为80px

          // 设置当前列标题宽度
          headerCell.style.width = `${newWidth}px`;
          headerCell.style.flex = 'none'; // 禁用flex自动调整

          // 设置所有数据行中相同位置的单元格宽度
          for (let i = 1; i < allRows.length; i++) {
            const row = allRows[i];
            if (row.className === 'web-element-selector-item') {
              const cells = row.children;
              if (columnIndex < cells.length) {
                cells[columnIndex].style.width = `${newWidth}px`;
                cells[columnIndex].style.flex = 'none'; // 禁用flex自动调整
              }
            }
          }
        };

        const mouseUpHandler = () => {
          document.removeEventListener('mousemove', mouseMoveHandler);
          document.removeEventListener('mouseup', mouseUpHandler);
        };

        document.addEventListener('mousemove', mouseMoveHandler);
        document.addEventListener('mouseup', mouseUpHandler);
      });
    }

    // 自动识别网站类型并初始化对应的选择器
    detectSiteType() {
      const hostname = window.location.hostname;

      // 简化后只返回网站类型，不执行任何自动选择操作
      if (hostname.includes('qidian.com')) {
        return 'qidian';
      } else if (hostname.includes('iqiyi.com')) {
        return 'iqiyi';
      }

      return 'unknown';
    }

    // Aqua风格推荐定位器生成
    generateAquaLocator(element) {
      // 1. 语义属性优先
      const semanticAttrs = ['data-testid', 'aria-label', 'role', 'placeholder', 'alt', 'title'];
      for (const attr of semanticAttrs) {
        const value = element.getAttribute && element.getAttribute(attr);
        if (value) {
          const selector = `[${attr}="${value}"]`;
          if (this.isUniqueSelector(selector, element)) {
            return selector;
          }
        }
      }

      // 2. 唯一文本内容（仅适用于button、a、span、div等常见标签）
      const tag = element.tagName.toLowerCase();
      const text = element.innerText?.trim();
      if (text && text.length > 0 && ['button', 'a', 'span', 'div', 'li', 'p'].includes(tag)) {
        // 避免过长文本
        const shortText = text.length > 30 ? text.substring(0, 30) : text;
        // 只允许无引号文本
        if (!shortText.match(/["'`]/)) {
          // 只考虑唯一的text定位
          const selector = `${tag}:has-text(\"${shortText}\")`;
          if (this.isUniqueSelector(selector, element)) {
            return selector;
          }
        }
      }

      // 3. 结构化CSS（父ID+标签、类名、属性等）
      // 先尝试getSimpleCssSelector
      const cssSelector = this.getSimpleCssSelector(element);
      if (cssSelector && this.isUniqueSelector(cssSelector, element)) {
        return cssSelector;
      }
      // 再尝试父级递归
      let parent = element.parentElement;
      let deep = 0;
      while (parent && deep < 2) {
        if (parent.id) {
          const selector = `#${parent.id} > ${tag}`;
          if (this.isUniqueSelector(selector, element)) {
            return selector;
          }
        }
        parent = parent.parentElement;
        deep++;
      }

      // 4. 回退到XPath
      const xpath = this.getSimpleXPath(element);
      // XPath唯一性校验需用evaluate
      if (this.isUniqueXPath(xpath, element)) {
        return xpath;
      }

      // 5. 找不到唯一推荐定位器，返回空字符串
      return '';
    }

    // 判断CSS选择器是否唯一且指向本元素
    isUniqueSelector(selector, element) {
      try {
        const nodes = document.querySelectorAll(selector);
        return nodes.length === 1 && nodes[0] === element;
      } catch {
        return false;
      }
    }

    // 判断XPath是否唯一且指向本元素
    isUniqueXPath(xpath, element) {
      try {
        const result = document.evaluate(xpath, document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
        return result.snapshotLength === 1 && result.snapshotItem(0) === element;
      } catch {
        return false;
      }
    }
  }

  // 保存实例到全局变量，避免重复初始化
  window.webElementSelector = new WebElementSelector();
})(); 